package de.hmm.hwip.osgi.ipc;

import java.util.ArrayList;

import de.hmm.hwip.service.MessengerService;

import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
/**
 * Handler to manage the hardware-services which are connected to the Framework
 * 
 * Every new service is added to list and identified by integer value
 *  
 * @author johannes mendel
 *
 */
public class IpcMessageHandler extends Handler {
	
	private static final String TAG = "MessageHandler";
	
    /** Keeps track of all current registered clients. */
    private static ArrayList<Messenger> mClients = new ArrayList<Messenger>();
    
	/** Messagetypes of remote services */ 
    static final int MSG_REGISTER_CLIENT = 1;
    static final int MSG_UNREGISTER_CLIENT = 2;
    static final int MSG_DATA_BUNDLE = 3;
    static final int MSG_OK = 8;
    static final int MSG_FAIL = 9;
   
    /** Identifier of client. */
    private int mClient = 0;
    
    /** Class constructor */
    public IpcMessageHandler(){
		mClients.add(0, null);
    }
    
	@Override
	public void handleMessage(Message msg) {
		boolean sendOK = false;
		
		System.out.println("Message: " + msg.what + " , " + msg.getData().keySet() + " , " + msg.arg1);
		if(msg != null){
			mClient = msg.arg1;
			switch (msg.what) {
			
			case MSG_REGISTER_CLIENT:
				mClients.add(mClient, msg.replyTo);
				Log.i(TAG, "Added remote client: " + msg.arg1);
				break;
				
			case MSG_UNREGISTER_CLIENT:
				mClients.remove(msg.replyTo);
				Log.i(TAG, "remote client removed: " + msg.arg1);
				break;
				
			case MSG_DATA_BUNDLE:
				int receiver = msg.arg1;
				try {
					int count = 0;
					synchronized (this) {
						while (!sendOK){
							sendOK = MessengerService.sendMsg(msg);
							wait(3000);
							count ++;
							if(count >= 10)
								break;
						}
					}
				} catch (Exception e) {
					sendOK = false;
					Log.e(TAG, e.getMessage());
				}
				try {
					if(mClients.contains(receiver)){
						Message reMsg = Message.obtain(null, sendOK ? MSG_OK : MSG_FAIL);
						mClients.get(receiver).send(reMsg);
					}
				} catch (RemoteException e) {
					mClients.remove(receiver);	
					Log.e(TAG, e.getMessage());
				}
				Log.i(TAG, sendOK ? "Message sended" : "Message failed");
				
				break;
				
			default:
				super.handleMessage(msg);
			}
		}
	}
	
	/**
	 * sends message back to service
	 * @param radio - identifier of radio service
	 * @param msg - data to send
	 */
	public static void sendMessage(int radio, Message msg){
		msg.what = MSG_DATA_BUNDLE;
		try {
			mClients.get(radio).send(msg);
		} catch (RemoteException e) {
			Log.e(TAG, e.getMessage());
		}
	}
}
